package com.lost.octopus.es.processor.service.common;


import com.sunsharing.share.common.mapper.JsonMapper;
import com.lost.octopus.es.processor.entity.commom.AddMappingInfo;
import com.lost.octopus.es.processor.entity.commom.ServiceInvoker;
import com.lost.octopus.es.processor.util.ApplicationUtil;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.PutMappingRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.ReflectionUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.lang.reflect.Method;

/**
 * 通用服务
 * @author zhangbh
 * @date 2025/4/14 10:33
 */
@Log4j2
@Service
public class CommonService {

    @Resource
    private RestHighLevelClient restHighLevelClient;


    /**
     * 指定参数添加mapping字段信息
     * 例如：{"properties":{"add_file1":{"type":"keyword"}}}
     */
    public void addMapping(AddMappingInfo info) {
        PutMappingRequest request = new PutMappingRequest(info.getIndexName());
        request.source(info.getMappingConfig());
        AcknowledgedResponse response;
        try {
            response = restHighLevelClient.indices().putMapping(request, RequestOptions.DEFAULT);
            log.info("es增加索引mapping {},参数={}", response.isAcknowledged(), JsonMapper.nonNullMapper().toJson(info));
        } catch (IOException e) {
            throw new RuntimeException("es增加索引mapping信息有误,请求参数:", e);
        }

        // 执行成功后，检查调用对应的初始化服务
        if (response.isAcknowledged()) {
            invokeInitService(info);
        }
    }

    /**
     * 调用某个springBean服务
     */
    public void invokeInitService(ServiceInvoker info) {
        String serviceName = info.getServiceName();
        if (StringUtils.isBlank(serviceName)) {
            return;
        }
        // 1. 获取目标 Bean
        Object targetBean = ApplicationUtil.getBean(serviceName);

        // 2. 查找匹配的方法（不考虑参数类型）
        Method method = ReflectionUtils.findMethod(targetBean.getClass(), info.getMethodName(), null);
        if (method == null) {
            throw new IllegalArgumentException("方法 '" + info.getMethodName() + "' 不存在或参数类型不匹配");
        }
        // 3. 调用方法
        try {
            log.info("调用初始化方法成功,参数:{}", JsonMapper.nonNullMapper().toJson(info));
            if (info.getParams() == null) {
                ReflectionUtils.invokeMethod(method, targetBean);
            } else {
                ReflectionUtils.invokeMethod(method, targetBean, info.getParams());
            }
        } catch (Exception e) {
            log.error("调用初始化方法失败,参数:" + JsonMapper.nonNullMapper().toJson(info), e);
            throw new RuntimeException("调用初始化方法失败", e);
        }
    }
}
